package com.ikingtech.framework.sdk.user.extension.caller;

import com.ikingtech.framework.sdk.core.response.R;
import com.ikingtech.framework.sdk.enums.common.FrameworkServerFeedbackTypeEnum;
import com.ikingtech.framework.sdk.user.extension.model.UserInfoEvent;
import com.ikingtech.framework.sdk.utils.Tools;
import com.ikingtech.framework.sdk.web.support.server.FrameworkServerFeedbackCaller;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.util.Set;

import static com.ikingtech.framework.sdk.cache.constants.CacheConstants.USER_EVENT_REMINDER;
import static com.ikingtech.framework.sdk.context.constant.SecurityConstants.GLOBAL_TOKEN;

/**
 * @author tie yan
 */
@Slf4j
@RequiredArgsConstructor
public class UserServerFeedbackCaller implements FrameworkServerFeedbackCaller {

    private final StringRedisTemplate redisTemplate;

    private final LoadBalancerClient loadBalancerClient;

    /**
     * 调用方法，根据不同的事件类型执行不同的操作
     * @param data 事件对象
     * @return 返回执行结果
     */
    @Override
    public R<Object> call(Object data) {
        UserInfoEvent event = (UserInfoEvent) data;
        return switch (event.getType()) {
            // 执行添加事件操作
            case ADD -> this.execute("/user/event/add", Tools.Json.toJsonStr(event));
            // 执行删除事件操作
            case DELETE -> this.execute("/user/event/delete", event.getId());
            // 执行更新事件操作
            case UPDATE -> this.execute("/user/event/update", Tools.Json.toJsonStr(event));
        };
    }

    @Override
    public FrameworkServerFeedbackTypeEnum type() {
        return FrameworkServerFeedbackTypeEnum.USER_INFO_FEEDBACK;
    }

    /**
     * 执行用户反馈接口
     * @param uri 接口地址
     * @param param 请求参数
     * @return 返回结果
     */
    private R<Object> execute(String uri, String param) {
        // 获取用户提醒集合
        Set<String> reporters = this.redisTemplate.opsForSet().members(USER_EVENT_REMINDER);
        if (Tools.Coll.isNotBlank(reporters)) {
            // 遍历用户提醒集合
            Tools.Coll.distinct(reporters).forEach(reporter -> {
                // 选择服务实例
                ServiceInstance client = this.loadBalancerClient.choose(reporter);
                if (null != client) {
                    try {
                        // 发送HTTP请求
                        String resultStr = Tools.Http.post(Tools.Http.SCHEMA_HTTP + client.getHost() + ":" + client.getPort() + uri, param, GLOBAL_TOKEN);
                        log.error("user feedback result[{}]", resultStr);
                    } catch (Exception e) {
                        log.error("user feedback exception[{}]", e.getMessage());
                    }
                }
            });
        }
        return R.ok();
    }

}
